import { load } from 'cheerio'
import axios from 'axios'
import vm from 'node:vm'
import fs from 'fs'
import dayjs from 'dayjs'

import ShopGoldEntity from '../entity/shopGold.js'
import BankGoldEntity from '../entity/bankGold.js'

import { shopDetailList } from './config.js'
import { dataSource } from '../db/index.js'

const queryString = `?share_token=5437c734-ab20-40a7-98ae-c7341b50bb4a&tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_android&utm_campaign=client_share`
const bankListUrl = `https://comment.10jqka.com.cn/qht/toutiao/banklist.html${queryString}`

const shopListUrl = `https://comment.10jqka.com.cn/qht/toutiao/shoplist.html${queryString}`

const shopGoldRepository = dataSource.getRepository(ShopGoldEntity)

const bankGoldRepository = dataSource.getRepository(BankGoldEntity)

/**
 * 获取网页的HTML内容-字符串
 * @param {string} url
 */
const getPageText = async (url) => {
  try {
    let response = await axios.get(url, {
      headers: {
        'User-Agent':
          'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60'
      }
    })

    return response.data
  } catch (error) {
    console.log('获取网页报错')
    console.log(err)
    return null
  }
}

const analysisHTML = (text, index, errMsg) => {
  const $ = load(text)

  let allScripts = $('script')

  if (allScripts.length) {
    let target = allScripts[index]

    if (!target) return null

    try {
      let dataText = target.children[0].data

      const context = vm.createContext({})
      vm.runInContext(dataText, context)

      return context
    } catch (error) {
      console.log(errMsg || '解析具体js数据报错')
      console.log(error)
      return null
    }
  }
}

/**
 * 查询品牌黄金近半个月的价格
 */
export const getShopDetailInfo = async () => {
  let tody = dayjs().format('YYYY-MM-DD')

  for (let i = 0, len = shopDetailList.length; i < len; i++) {
    console.log(`解析： ${shopDetailList[i].name} 详情数据中...\n`)

    let text = await getPageText(shopDetailList[i].url)

    let result = analysisHTML(text, 1, shopDetailList[i].name + '-品牌黄金解析失败')

    if (result) {
      if (result.shopinfo) {
        let auList = []

        let goods = result.shopinfo.goods || []

        if (goods[0] && goods[0].logs && goods[0].logs.length) {
          auList = goods[0].logs.map((item) => {
            return {
              ...item,
              createTime: dayjs(item.date).format('YYYY-MM-DD HH:mm:ss'),
              type: result.shopinfo.code
            }
          })
        }

        console.log('商店金价近15天数据解析完成')

        // 存储数据
        saveShopGoldData(auList)
      }
    }
  }
}

const saveShopGoldData = async (list) => {
  let startTime = dayjs().subtract(15, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
  let endTime = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')

  try {
    // 创建日期就是金价日期
    // 一天可能定时任务存在多次更新
    let rows = await shopGoldRepository.query(
      `select * from shop_gold where type="${list[0].type}" and createTime Between "${startTime}" and "${endTime}"`
    )

    if (rows.length !== 0) {
      // 给list中将id赋值
      for (let i = 0; i < list.length; i++) {
        for (let j = 0; j < rows.length; j++) {
          let newTime = dayjs(list[i].createTime).format('YYYY-MM-DD')
          let oldTime = dayjs(rows[j].createTime).format('YYYY-MM-DD')

          if (oldTime === newTime) {
            list[i].id = rows[j].id

            // 只更新今天的日期字段
            if (newTime === dayjs().format('YYYY-MM-DD')) {
              list[i].updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
            }
          }
        }
      }

      let records = list.filter((p) => p.id)

      // 新增的数据
      let addRecords = list.filter((p) => !p.id)

      await shopGoldRepository.save(records)

      // 定时任务走过的时候，过了24点
      if (addRecords.length) {
        addRecords.forEach((p) => {
          p.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
        })

        await shopGoldRepository.save(addRecords)
      }
    } else {
      list.forEach((p) => {
        p.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
      })

      // 第一次进来
      await shopGoldRepository.save(list)
    }
  } catch (error) {
    console.log('插入数据异常')
    console.log(error)
  }
}

export const getCurrentPrice = async () => {
  let shopPageText = await getPageText(shopListUrl)

  const today = dayjs().format('YYYY-MM-DD')

  if (shopPageText) {
    const shopData = analysisHTML(shopPageText, 1, '品牌黄金解析失败')
    fs.writeFile(`./history/shopData-${today}.json`, JSON.stringify(shopData, null, 2), (err) => {})
  }
}

/**
 * 存储银行的数据
 * @typedef {TBank = {name:string, code: string, goods: string, logs: Array<any>}} TBank
 * @param {Array<TBank>} list
 */
const saveBankList = async (list) => {
  let startTime = dayjs().subtract(15, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss')
  let endTime = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')
  try {
    for (let i = 0, len = list.length; i < len; i++) {
      // 银行类型
      let type = list[i].code

      let rows = await bankGoldRepository.query(
        `select * from bank_gold where type="${type}" and createTime Between "${startTime}" and "${endTime}"`
      )
      // console.log(rows);

      // 对部分数据做更新
      if (rows.length !== 0) {
        let logs = list[i].logs || []

        logs.forEach((p) => {
          p.type = type
          p.createTime = dayjs(p.date).format('YYYY-MM-DD HH:mm:ss')
        })

        // 给list中将id赋值
        for (let i = 0; i < logs.length; i++) {
          for (let j = 0; j < rows.length; j++) {
            let newTime = dayjs(logs[i].createTime).format('YYYY-MM-DD')
            let oldTime = dayjs(rows[j].createTime).format('YYYY-MM-DD')

            if (oldTime === newTime) {
              logs[i].id = rows[j].id
              logs[i].updateTime = rows[j].updateTime

              // 只更新今天的日期字段
              if (newTime === dayjs().format('YYYY-MM-DD')) {
                logs[i].updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
              }
            }
          }
        }

        let records = logs.filter((p) => p.id)

        // 新增的数据
        let addRecords = logs.filter((p) => !p.id)

        if (records.length) {
          await bankGoldRepository.save(records)
        }

        console.log(records)

        // 定时任务走过的时候，过了24点
        if (addRecords.length) {
          addRecords.forEach((p) => {
            p.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
          })

          await bankGoldRepository.save(addRecords)
        }
      } else {
        console.log('不应该执行')
        let arr = list[i].logs || []

        arr.forEach((p) => {
          p.type = type
          p.createTime = dayjs(p.date).format('YYYY-MM-DD HH:mm:ss')
          p.updateTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
        })
        // 直接写入
        bankGoldRepository.save(arr)
      }
    }
  } catch (error) {
    console.log('【saveBankList】 银行数据插入更新异常')
    console.log(error)
  }
}

/**
 * 查询银行的价格
 */
export const getBankPrice = async () => {
  let bankPageText = await getPageText(bankListUrl)

  if (bankPageText) {
    const res = analysisHTML(bankPageText, 1, '银行列表数据解析失败')

    console.log(res)

    if (res.banklist && res.banklist.length) {
      saveBankList(res.banklist)
    }
  }
}

// getCurrentPrice()

// getShopDetailInfo()
